
/* Generated by Interface Builder */

#import "WorkspaceManager.h"
#import "MenuManager.h"
#import "ClassManager.h"
#import "NuString.h"
#import "NuText.h"
#import "MenuManager.h"
#import "PrefsManager.h"
#import <appkit/NXRTFDErrors.h>
#import <appkit/Application.h>
#import <appkit/Text.h>
#import <appkit/Panel.h>
#import <appkit/NXBrowser.h>
#import <appkit/ScrollView.h>
#import <appkit/TextField.h>
#import <appkit/OpenPanel.h>
#import <defaults/defaults.h>
#import <objc/List.h>
#import <objc/objc-load.h>
#import <objc/Storage.h>
#import <stdlib.h>
#import <strings.h>
#import  <sys/file.h>
#import <sys/types.h>
#import <sys/stat.h>
#import <libc.h>
#include <ctype.h>

extern id Nu ;

@implementation WorkspaceManager

- addToLineList: (int) lineNum ;
{ // add lineNum to the list of lines
  [lineList addElement: &lineNum] ;
  return self ;
}


- (char *) bareFileName ;
{ // return pointer to my fileName, minus any path
  char *cursor ;
  if(cursor = rindex(fileName, '/'))
    cursor++ ;
  else
    cursor = fileName ;
  return cursor ;
}

- evalSelection:sender
{ return [textView evalSelection: sender] ;
}


- extension: (char *) extension ;
{ // check that fileName has the given extension...
  // if not, then make sure it does.  extension should
  // not include the "." character
  char * currentExt ;
  currentExt =  rindex(fileName,'.') ;
  if(!currentExt) 
  { // currently has no extension at all...
    strcat(fileName,".") ;
    strcat(fileName,extension) ;
  }
  // if current extension if rtf and it should be rtfd, then
  // just plunk on a d.  ...
  else if(!strcmp(currentExt,".rtf") && !strcmp(extension,"rtfd"))
  {  // must remove the .rtf file
     struct stat statBuf ;
     if(!stat(fileName,&statBuf))
       unlink(fileName) ;
     strcat(fileName,"d") ;
  }
  // now reflect new name in our window...
  [self setFancyTitle] ;
  return self ;
}

- (char *) extension ;
{ // provide file extension
  if([textView isRTFD])
   return "rtfd" ;
  else
    return "rtf" ;
}

- (char *) fileName ;
{ return fileName ;
}

- fileName: (char *) fname ;
{ // copy fname into ivar, set the
  // window's title to fname, with the
  // filename followed by the path
  if(fileName)
  { if(!strcmp(fileName,fname))
      return self ; // fileName isn't changing
    else
      free(fileName) ;
  }
  // allocate memory for fileName; leave room to
  // add an extension
  fileName = (char *) malloc(strlen(fname) + 8) ;
  strcpy(fileName, fname) ;
  return [self setFancyTitle] ; // set title of window
  return self ;
}
 
- free ;
{ free(fileName) ;
  return [super free] ;
}

- init ;
{ [textView setDelegate: self] ;
  [self setDelegate: Nu] ;
  lineList = [[Storage alloc] initCount: 0
                       elementSize: sizeof(int)
                       description: "i"] ;
  // make sure we are not monofont so we can
  // do rich text
  [textView setMonoFont: NO] ;
  isRTF = YES ;
  [self setMiniwindowIcon: "wsdIcon.tiff"] ;
  return self ;
}
    
- lineList ;
{ // return the Storage List of lineNums
  return lineList ;
}

- message: (char *) aMsg ;
{ // show aMsg in the msgField
  [msgField setStringValue: aMsg] ;
  NXPing() ;
  [self flushWindow] ;
  return self ;
}


- readFile ;
// read "fileName" into the text object. 
{ if(fileName[0] != '\0')
  { [self message: "Reading file..."] ;
    if(!strcmp(&fileName[strlen(fileName) - 4],".rtf"))
    { // open an rtf file
      NXStream *fileStream ;
      if((fileStream = NXMapFile(fileName,NX_READONLY)) != NULL)
        [textView readRichText: fileStream] ;
      NXCloseMemory(fileStream,NX_FREEBUFFER);
    }
    else if(!strcmp(&fileName[strlen(fileName) - 5],".rtfd"))
    { // open an rtfd file package
      if([textView openRTFDFrom: fileName] != NX_RTFDErrorNone) 
         NXRunAlertPanel("Nu", "Error, couldn't read: %s",
          NULL,NULL,NULL,fileName) ;
    }
    else 
    { // open file which is neither rtf nor rtfd.
      NXStream *fileStream ;
      if((fileStream = NXMapFile(fileName,NX_READONLY)) != NULL)
        [textView readText: fileStream] ;
      NXCloseMemory(fileStream,NX_FREEBUFFER);
    }
  }
  [self message: ""] ;
  [self setDocEdited: NO] ;
  return self ;
}

- removeFromLineList: (int) lineNum ;
{ // remove lineNum from the list of lines
  if(lineList != nil)    
   [lineList removeAt: lineNum] ;
  return self ;
}
  
-revert:sender ;
{ if([self isDocEdited])
  { int rval = NXRunAlertPanel(
     "Nutation","This window has been edited. Revert?",
      "REVERT","CANCEL",NULL) ;
    if(rval)
      return [self readFile] ;
    else
      return nil ;
  }
  return self ;
}

-(BOOL) save:sender ;
{ if([self isDocEdited])
  { if(!fileName) // no fileName, i.e. first save:
      return [self saveAs: sender] ;
    else
      return [self saveTextToFileName] ;
  }
  return YES ;
}


-(BOOL) saveAs:sender ;
{ id savePanel = [SavePanel new] ;
  [savePanel setRequiredFileType: [self extension]] ;
  if([savePanel runModalForDirectory: NULL file: fileName])
  { [self fileName: (char *) [savePanel filename]] ;
    return [self saveTextToFileName] ;
  }
  else
    return NO ;
}


-(BOOL) saveTextToFileName ;
// pre:  -ivar fileName contains a valid
//       file pathname.
//       -ivar textView contains a TextView object
// post: if file can be opened or created, with mode
//       644: text of textView is written out to the
//       file named by fileName; file is closed, and
//       YES is returned.
//       otherwise returns NO
{ // removeBackup should be a dwrite...some day!
  int rval ;
  [self message: "Saving file..."] ;
  if([textView isRTFD])
  { const char *theFlags ;
    [self extension: "rtfd"] ; // ensure rtfd extension
    theFlags = NXGetDefaultValue([NXApp appName],"Flags") ;
    rval = [textView saveRTFDTo:fileName 
                 removeBackup: theFlags[BACKUPRTF]  == '1' 
                 errorHandler: NULL] ;
    if(rval != NX_RTFDErrorNone)
    { NXRunAlertPanel("Nu","Couldn't save: %s\n",
      NULL,NULL,NULL,fileName) ;
      return NO ;
    }
  }
  else // we should check for rtf errors...some day!
  { NXStream *aStream = NXOpenMemory(NULL,0, NX_WRITEONLY);
    [self extension: "rtf"] ;   	
    [textView writeRichText:aStream];	
    NXSaveToFile(aStream, fileName);
    NXCloseMemory(aStream, NX_FREEBUFFER);	
  }
  [self message: ""] ;
  [self setDocEdited: NO] ;
  return YES ;
}

- setFancyTitle ;
{ // update the title from the fileName
  char *fullName, *name ;
  int nameLen ;
  nameLen = strlen(fileName) + 1 ;
  fullName = (char *) alloca(nameLen) ;
  strcpy(fullName, fileName) ;
  name = rindex(fullName,'/') ;
  if(name) // is there is a path,
  { char title[nameLen] ;
    name[0] = '\0' ; // split string into 2 pieces
    name++ ;
    sprintf(title,"%s  %s",name,fullName) ;
    [self setTitle: title] ;
  }
  else // no path, just use the filename
    [self setTitle: fileName] ;
}

- setTextView: sender ;
{ // remove sender's docView from hierarchy and replace
  // with an instance of MMText 
  textView = [sender docView] ;
  return self ;
}

- textDidGetKeys:text isEmpty:(BOOL)empty ;
{ // this is a delegate message for the textView
  if(![self isDocEdited])
     [self setDocEdited: YES] ;
  return NO;
}

- textWillConvert:sender fromFont:from toFont:to ;
{ if(![self isDocEdited])
   [self setDocEdited: YES] ;
  return to ;
}

- textView ;
{ return textView ;
}

- read: (NXStream *) aStream ;
{ [super read: aStream] ;
  NXReadArray(aStream, "c", 256, fileName) ;
  textView = NXReadObject(aStream) ;
  msgField = NXReadObject(aStream) ;
  lineList = NXReadObject(aStream) ;
  [self setDelegate: NXReadObject(aStream)] ;
  return self ;
}

- write: (NXStream *) aStream ;
{ [super write: aStream] ;
  NXWriteArray(aStream, "c", 256, fileName)  ;
  NXWriteObjectReference(aStream,textView) ;
  NXWriteObjectReference(aStream,msgField) ;
  NXWriteObject(aStream,lineList) ;
  NXWriteObjectReference(aStream,delegate) ;
  return self ;
}


@end
